﻿// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved. 
// Licensed under the Apache License, Version 2.0.  
// See License.txt in the project root for license information.

using CompatCheckAndMigrate.Helpers;
using CompatCheckAndMigrate.ObjectModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace CompatCheckAndMigrate.Controls
{
    public partial class MigrationCandidatesControl : UserControl, IWizardStep
    {
        private BackgroundWorker _worker;
        private RemoteSystemInfo _remoteSystemInfo;

        public MigrationCandidatesControl()
        {
            InitializeComponent();
        }

        public event EventHandler<GoToWizardStepEventArgs> GoTo;

        public void SetState(object state, bool isNavigatingBack = false)
        {
            if (!isNavigatingBack) {
                _remoteSystemInfo = state as RemoteSystemInfo;
                ProcessIISInfo();
            }
            else {
                //
                // repopulate everything, since we've pruned the lists.
                //
                if (null != _remoteSystemInfo) {
                    ProcessIISInfo();
                }
            }
        }

        private void FireGoToEvent(WizardSteps step, object state = null, bool isNavigatingBack = false)
        {
            EventHandler<GoToWizardStepEventArgs> _goTo = GoTo;
            if (_goTo != null)
            {
                _goTo(this, new GoToWizardStepEventArgs(step, state, isNavigatingBack));
            }
        }

        public IISServer Server { get; private set; }

      

        private void GetSelectedSites()
        {
            List<Site> selectedSites = new List<Site>();
            List<Database> selectedDbs = new List<Database>();
           
            foreach(TreeNode node in this.websiteCheckedTreeList.Nodes)
            {
                if(node.Checked)
                {
                    if(typeof(Site)==node.Tag.GetType())
                    {
                        ((Site)node.Tag).Databases.Clear();
                        selectedSites.Add((Site)node.Tag);
                    }
                    else if (typeof(Database) == node.Tag.GetType())
                    {
                        selectedDbs.Add((Database)node.Tag);
                    }
                }
                foreach (TreeNode child in node.Nodes)
                {
                    if (child.Checked)
                    {
                        if (typeof(Site) == child.Tag.GetType())
                        {
                            ((Site)child.Tag).Databases.Clear();
                            selectedSites.Add((Site)child.Tag);
                        }
                        else if (typeof(Database) == child.Tag.GetType())
                        {
                            selectedDbs.Add((Database)child.Tag);
                        }
                    }
                }
            }
            
            foreach(Database db in selectedDbs)
            {
                db.ParentSite.Add(db);
                db.ParentSite = null;
            }
            this.Server.Sites = selectedSites;
        }

        

        private void StartButton_Click(object sender, EventArgs e)
        {
            GetSelectedSites();

            FireGoToEvent(WizardSteps.ReadinessReport, this.Server);
        }

        private void ProcessIISInfo()
        {
            // Hide listbox and show busy animation.
            this.descriptionLabel.Visible = this.websiteCheckedTreeList.Visible = this.StartButton.Visible = this.btnBack.Visible = false;
            this.busyPictureBox.Visible = this.busyMessageLabel.Visible = true;
            if (_remoteSystemInfo != null)
            {
                this.busyMessageLabel.Text = "Please wait while we inspect " + _remoteSystemInfo.ComputerName +
                                             " for migration candidates";
            }
            // Start local websites scan in a background thread.
            _worker = new BackgroundWorker();
            _worker.DoWork += (object doWorkSender, DoWorkEventArgs doWorkEventArgs) =>
            {
                // Do actual work here.
                IISInfoReader reader = Helper.GetIISInfoReader(Helper.AzureMigrationId, _remoteSystemInfo);

                doWorkEventArgs.Result = reader;
            };

            _worker.RunWorkerCompleted += (object runWorkerCompletedSender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs) =>
            {
                // Hide busy animation.
                this.busyPictureBox.Visible = this.busyMessageLabel.Visible = false;
                if (runWorkerCompletedEventArgs.Error != null || Helper.IisVersion < 6)
                {
                    Helper.ShowErrorMessageAndExit(runWorkerCompletedEventArgs.Error.Message);
                }

                if (runWorkerCompletedEventArgs.Result == null)
                {
                    Helper.ShowErrorMessageAndExit("IIS Configuration could not be read. Please re run the tool");
                }

                this.websiteCheckedTreeList.Nodes.Clear();
                
                
                // Get result from the async task.
                IISInfoReader reader = (IISInfoReader)runWorkerCompletedEventArgs.Result;

                // Save server object for later use.
                this.Server = reader.Server;

                // Display candidate web sites
                foreach (Site site in reader.Server.Sites)
                {
                    TreeNode sn = new TreeNode(site.ToString(),1,1) { Tag = site, Checked = true, };
                    

                     // We rely on Site::ToString() to display the name of the site.
                    foreach(Database db in site.Databases)
                    {
                        sn.Nodes.Add(new TreeNode(db.ToString(),5,5) { Tag = db, Checked = true, });
                    }

                    websiteCheckedTreeList.Nodes.Add(sn);
                    sn.Checked = true;
                    
                }


                this.websiteCheckedTreeList.ExpandAll();
                // Show listbox with results.
                this.websiteCheckedTreeList.Visible = this.descriptionLabel.Visible = this.StartButton.Visible = this.btnBack.Visible = true;
            };

            _worker.RunWorkerAsync();
        }

        private void MigrationCandidatesControl_Load(object sender, EventArgs e)
        {
            Server = null;
            //ProcessIISInfo();
        }

        private void licenseAgreementLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Helper.OpenWebLink(Helper.LicenseLink);
        }

        private void codeplexRepoLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Helper.OpenWebLink(Helper.CodePlexRepoLink);
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            FireGoToEvent(WizardSteps.RemoteComputerInfo, null, true);
        }

        void websiteCheckedTreeList_AfterCheck(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
            TreeNode node = e.Node;

            //
            // If this node has children, then sync their checked status.
            //
            if ((null != node.Nodes) && (node.Nodes.Count != 0)) {
                foreach (TreeNode child in e.Node.Nodes) {
                    if (child.Checked != node.Checked) {
                        child.Checked = node.Checked;
                    }
                }
            }

            //
            // If this is a child node, and it's been checked, make sure its
            // parent nodes are checked.
            //
            if (node.Checked) {
                TreeNode nodeParent = node.Parent;
                while (null != nodeParent) {
                    if (!nodeParent.Checked) {
                        nodeParent.Checked = true;
                    }
                    nodeParent = nodeParent.Parent;
                }

                this.StartButton.Enabled = true;
                return;
            }

            //
            // Ensure that at least one Site is selected, else disabled the Next button.
            //

            TreeView tv = null;

            if (null != node.TreeView) {
                tv = node.TreeView;
            }
            else {
                TreeNode nodeParent = node.Parent;
                while (null != nodeParent) {
                    if (null != nodeParent.TreeView) {
                        tv = nodeParent.TreeView;
                        break;
                    }
                    nodeParent = nodeParent.Parent;
                }
            }

            if (null == tv) {
                //MessageBox.Show("ERROR: No TreeView");
                return;
            }

            if (typeof(Site) == node.Tag.GetType()) {
                if (node.Checked) {
                    this.StartButton.Enabled = true;
                }
                else {
                    TreeNodeCollection trCol = tv.Nodes;
                    this.StartButton.Enabled = false;
                    foreach (TreeNode child in trCol) {
                        if ((typeof(Site) == child.Tag.GetType()) &&
                            (child.Checked)) {
                            this.StartButton.Enabled = true;
                            break;
                        }
                    }
                }

            }

        }

    }
}
